package com.caocaog.market.utils;

import com.caocaog.market.entity.*;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 易联云、飞鹅、芯烨云多列排版工具类
 *
 * @author chechen
 */
public class PrintUtil {

    private PrintUtil() {
    }

    /**
     * 获取符合易联云打印格式的文本
     *
     * @param index         编号
     * @param orderBase     订单基础信息
     * @param orderLineList 商品订单行列表
     * @param orderPay      订单支付信息
     * @param orderDelivery 订单配送信息
     * @param shopBasic     店铺信息
     * @return 要打印的文本
     */
    public static String getYlyPrintString(int index, OrderBase orderBase, List<OrderLine> orderLineList, OrderPay orderPay, OrderDelivery orderDelivery, ShopBasic shopBasic) {
        boolean isRefundOrder = "-2".equals(orderBase.getStatus());
        StringBuilder orderInfo = new StringBuilder();
        // 编号
        if (isRefundOrder) {
            orderInfo.append("<FS2><center>#").append(" 曹操来了</center></FS2>\n\n");
        } else {
            orderInfo.append("<FS2><center>#").append(index).append(" 曹操来了</center></FS2>\n\n");
        }
        // 店名
        orderInfo.append("<FH2><center>*").append(shopBasic.getName()).append("*</center></FH2>\n\n");
        if (isRefundOrder) {
            orderInfo.append("<FS2>订单申请退款</FS2>\n");
        } else if (orderBase.getType() == 2) {
            orderInfo.append("<FS2>自提订单</FS2>\n");
        } else {
            orderInfo.append("<FS2>期望：立即送达</FS2>\n");
        }
        orderInfo.append("<center>------------</center>\n");
        if (StringUtils.isNotBlank(orderBase.getRemark()))
            orderInfo.append("<FS2>备注：").append(orderBase.getRemark()).append("</FS2>\n");
        // 下单时间
        orderInfo.append("<FB>下单时间：").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderBase.getCreateTime())).append("</FB>\n");
        // 订单编号
        orderInfo.append("<FB>订单号：").append(orderBase.getOrderNo()).append("</FB>\n");
        orderInfo.append("<FH2><center>-----商品-----</center>\n");
        orderInfo.append("<table>");
        orderLineList.forEach(orderLine -> {
            orderInfo.append("<tr><td>").append(orderLine.getGoodsName()).append("/").append(orderLine.getNameStr()).append("</td><td>");
            if (orderLine.getQuantity() > 1) {
                orderInfo.append("【x").append(orderLine.getQuantity()).append("】</td><td>");
            } else {
                orderInfo.append("x1</td><td>");
            }
            orderInfo.append(orderLine.getTotalPrice()).append("</td></tr>");
        });
        orderInfo.append("</table></FH2>");
        if (isRefundOrder) {
            orderInfo.append("<FH2><center>********** #").append(" 完**********</center></FH2>");
        } else {
            orderInfo.append("<center>-----优惠-----</center>\n");
            orderInfo.append("打包费：<right>").append(orderPay.getPackAmount()).append("</right>\n");
            orderInfo.append("配送费：<right>").append(orderPay.getDeliveryAmount()).append("</right>\n");
            orderInfo.append("<center>**************************</center>\n");
            orderInfo.append("订单金额：<right>").append(orderPay.getAmount()).append("</right>\n");
            orderInfo.append("优惠金额：<right>").append(orderPay.getDiscountAmount()).append("</right>\n");
            orderInfo.append("<FS2>实付：<right>").append(orderPay.getPayAmount()).append("</right></FS2>\n");
            if (orderBase.getType() == 2) {
                orderInfo.append("<center>------自提用户信息------</center>\n").append("<FH2>");
            } else {
                orderInfo.append("<center>------收货地址------</center>\n").append("<FH2>");
                orderInfo.append(orderDelivery.getAddress()).append("\n");
            }
            orderInfo.append(orderDelivery.getName());
            if (orderDelivery.getSex() != null)
                orderInfo.append(orderDelivery.getSex() == 0 ? "（先生）" : "（女士）\n\n");
            orderInfo.append("手机号电话：").append(orderDelivery.getMobile()).append("\n");
            orderInfo.append("<center>********** #").append(index).append(" 完**********</center></FH2>");
        }
        return orderInfo.toString();
    }

    /**
     * 获取符合芯烨云打印格式的文本
     *
     * @param index         编号
     * @param orderBase     订单基础信息
     * @param orderLineList 商品订单行列表
     * @param orderPay      订单支付信息
     * @param orderDelivery 订单配送信息
     * @param shopBasic     店铺信息
     * @return 要打印的文本
     */
    public static String getXyyPrintString(int index, OrderBase orderBase, List<OrderLine> orderLineList, OrderPay orderPay, OrderDelivery orderDelivery, ShopBasic shopBasic) {
        boolean isRefundOrder = "-2".equals(orderBase.getStatus());
        StringBuilder orderInfo = new StringBuilder();
        // 编号
        if (isRefundOrder) {
            orderInfo.append("<CB>#").append(" 曹操来了</CB><BR><BR>");
        } else {
            orderInfo.append("<CB>#").append(index).append(" 曹操来了</CB><BR><BR>");
        }
        // 店名
        orderInfo.append("<C><HB>*").append(shopBasic.getName()).append("*</HB></C><BR><BR>");
        if (isRefundOrder) {
            orderInfo.append("<B>订单申请退款</B><BR>");
        } else if (orderBase.getType() == 2) {
            orderInfo.append("<B>自提订单</B><BR>");
        } else {
            orderInfo.append("<B>期望：立即送达</B><BR>");
        }
        orderInfo.append("<C>------------</C><BR>");
        if (StringUtils.isNotBlank(orderBase.getRemark())) {
            orderInfo.append("<B>备注：").append(orderBase.getRemark()).append("</B><BR>");
        }
        // 下单时间
        orderInfo.append("<BOLD>下单时间：").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderBase.getCreateTime())).append("</BOLD><BR>");
        // 订单编号
        orderInfo.append("<BOLD>订单号：").append(orderBase.getOrderNo()).append("</BOLD><BR>");
        orderInfo.append("<HB><C>----------商品----------</C><BR>");
        orderLineList.forEach(orderLine -> orderInfo.append(NoteFormatter.formatPrintOrderItem(
                orderLine.getGoodsName() + "/" + orderLine.getNameStr(),
                orderLine.getQuantity(),
                Double.parseDouble(orderLine.getTotalPrice())
        )));
        orderInfo.append("</HB>");
        if (isRefundOrder) {
            orderInfo.append("<C><HB>********** #").append(" 完**********</HB></C>");
        } else {
            orderInfo.append("<C>----------优惠----------</C><BR>");
            orderInfo.append("打包费：<R>").append(orderPay.getPackAmount()).append("</R><BR>");
            orderInfo.append("配送费：<R>").append(orderPay.getDeliveryAmount()).append("</R><BR>");
            orderInfo.append("<C>**************************</C><BR>");
            orderInfo.append("订单金额：<R>").append(orderPay.getAmount()).append("</R><BR>");
            orderInfo.append("优惠金额：<R>").append(orderPay.getDiscountAmount()).append("</R><BR>");
            orderInfo.append("<B>实付：<R>").append(orderPay.getPayAmount()).append("</R></B><BR>");
            if (orderBase.getType() == 2) {
                orderInfo.append("<C>-----------自提用户信息-----------</C><BR>").append("<HB>");
            } else {
                orderInfo.append("<C>-----------收货地址-----------</C><BR>").append("<HB>");
                orderInfo.append(orderDelivery.getAddress()).append("<BR>");
            }
            orderInfo.append(orderDelivery.getName());
            if (orderDelivery.getSex() != null) {
                orderInfo.append(orderDelivery.getSex() == 0 ? "（先生）" : "（女士）<BR><BR>");
            }
            orderInfo.append("手机号电话：").append(orderDelivery.getMobile()).append("</HB><BR>");
            orderInfo.append("<C><HB>********** #").append(index).append(" 完**********</HB></C>");
        }
        return orderInfo.toString();
    }

    /**
     * 获取符合中午打印格式的文本
     *
     * @param index         编号
     * @param orderBase     订单基础信息
     * @param orderLineList 商品订单行列表
     * @param orderPay      订单支付信息
     * @param orderDelivery 订单配送信息
     * @param shopBasic     店铺信息
     * @param cascadeCount  打印次数
     * @return 要打印的文本
     */
    public static String getZwPrintString(int index, OrderBase orderBase, List<OrderLine> orderLineList, OrderPay orderPay, OrderDelivery orderDelivery, ShopBasic shopBasic, Integer cascadeCount) {
        boolean isRefundOrder = "-2".equals(orderBase.getStatus());
        StringBuilder orderInfo = new StringBuilder();
        if (isRefundOrder) {
            // 多联次打印
            orderInfo.append("<N>").append(cascadeCount).append("</N>");
            orderInfo.append("<C><S2>#").append("曹操来了<S2></C><RN><RN>");
        } else {
            // 语音提示 6:您有新的订单，请注意查收
            orderInfo.append("<MS>6</MS>");
            // 多联次打印
            orderInfo.append("<N>").append(cascadeCount).append("</N>");
            // 编号
            orderInfo.append("<C><S2>#").append(index).append(" 曹操来了<S2></C><RN><RN>");
        }

        // 店名
        orderInfo.append("<C><S1>*").append(shopBasic.getName()).append("*</S1></C><RN><RN>");
        if (isRefundOrder) {
            orderInfo.append("<S1>订单申请退款</S1><RN>");
        } else if (orderBase.getType() == 2) {
            orderInfo.append("<S1>自提订单</S1><RN>");
        } else {
            orderInfo.append("<S1>期望：立即送达</S1><RN>");
        }
        orderInfo.append("<C>--------------------------------</C><RN>");
        if (StringUtils.isNotBlank(orderBase.getRemark())) {
            orderInfo.append("<S1>备注：").append(orderBase.getRemark()).append("</S1><RN>");
        }
        // 下单时间
        orderInfo.append("<B1>下单时间：").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderBase.getCreateTime())).append("</B1><RN>");
        // 订单编号
        orderInfo.append("<B1>订单号：").append(orderBase.getOrderNo()).append("</B1><RN>");
        orderInfo.append("<H2><C>--------------商品--------------</C><RN>");
        orderLineList.forEach(orderLine -> {
            orderInfo.append("<TR><TD>")
                    .append(orderLine.getGoodsName()).append("/").append(orderLine.getNameStr()).append("</TD><TD>");
            if (orderLine.getQuantity() > 1) {
                orderInfo.append("【x").append(orderLine.getQuantity()).append("】</TD><TD>");
            } else {
                orderInfo.append("x1</TD><TD>");
            }
            orderInfo.append(orderLine.getTotalPrice()).append("</TD></TR>");
        });
        orderInfo.append("</H2>");
        if (isRefundOrder) {
            orderInfo.append("<C><S2>************* #").append(" 完*************</S2></C>");
        } else {
            orderInfo.append("<C>--------------优惠--------------</C><RN>");
            orderInfo.append("打包费：").append(orderPay.getPackAmount()).append("<RN>");
            orderInfo.append("配送费：").append(orderPay.getDeliveryAmount()).append("<RN>");
            orderInfo.append("<C>********************************</C><RN>");
            orderInfo.append("订单金额：").append(orderPay.getAmount()).append("<RN>");
            orderInfo.append("优惠金额：").append(orderPay.getDiscountAmount()).append("<RN>");
            orderInfo.append("<S1>实付：").append(orderPay.getPayAmount()).append("</S1><RN>");
            if (orderBase.getType() == 2) {
                orderInfo.append("<C>------------自提用户信息------------</C><RN>").append("<S2>");
            } else {
                orderInfo.append("<C>------------收货地址------------</C><RN>").append("<S2>");
                orderInfo.append(orderDelivery.getAddress()).append("<RN>");
            }
            orderInfo.append(orderDelivery.getName());
            if (orderDelivery.getSex() != null) {
                orderInfo.append(orderDelivery.getSex() == 0 ? "（先生）" : "（女士）<RN><RN>");
            }
            orderInfo.append("手机号电话：").append(orderDelivery.getMobile()).append("</S2><RN>");
            orderInfo.append("<C><S2>************* #").append(index).append(" 完*************</S2></C>");
        }
        return orderInfo.toString();
    }

    /**
     * 获取符合飞鹅打印格式的文本
     *
     * @param index         编号
     * @param orderBase     订单基础信息
     * @param orderLineList 商品订单行列表
     * @param orderPay      订单支付信息
     * @param orderDelivery 订单配送信息
     * @param shopBasic     店铺信息
     * @return 要打印的文本
     */
    public static String getFePrintString(int index, OrderBase orderBase, List<OrderLine> orderLineList, OrderPay orderPay, OrderDelivery orderDelivery, ShopBasic shopBasic) {
        // b1代表名称列占用（14个字节）  b2单价列（6个字节） b3数量列（3个字节） b4金额列（6个字节）
        // 这里的字节数可按自己需求自由改写，14+6+3+6再加上代码写的3个空格就是32了，58mm打印机一行总占32个字节
        return getFePrintString(index, orderBase, orderLineList, orderPay, orderDelivery, shopBasic, 14, 6, 3, 6);
    }

    /**
     * 中间的代码是实现商品超出字数的自动换下一行对齐的处理，同时保持各列进行对齐
     * 排版原理是统计字符串字节数，补空格换行处理
     * 58mm的机器,一行打印16个汉字,32个字母;80mm的机器,一行打印24个汉字,48个字母
     *
     * @param b1 名称列占用字节
     * @param b2 单价列字节
     * @param b3 数量列字节
     * @param b4 金额列字节
     * @return 订单行的
     */
    public static String getFePrintString(
            int index,
            OrderBase orderBase,
            List<OrderLine> orderLineList,
            OrderPay orderPay,
            OrderDelivery orderDelivery,
            ShopBasic shopBasic,
            int b1, int b2, int b3, int b4) {
        boolean isRefundOrder = "-2".equals(orderBase.getStatus());
        StringBuilder orderInfo = new StringBuilder();
        // 编号
        if (isRefundOrder) {
            orderInfo.append("<CB>#").append(" 曹操来了</CB><BR><BR>");
        } else {
            orderInfo.append("<CB>#").append(index).append(" 曹操来了</CB><BR><BR>");
        }
        // 店名
        orderInfo.append("<L><C>*").append(shopBasic.getName()).append("*</C></L><BR><BR>");
        if (isRefundOrder) {
            orderInfo.append("<B>订单申请退款</B><BR>");
        } else if (orderBase.getType() == 2) {
            orderInfo.append("<B>自提订单</B><BR>");
        } else {
            orderInfo.append("<B>期望：立即送达</B><BR>");
        }
        orderInfo.append("<C>------------</C><BR>");
        if (StringUtils.isNotBlank(orderBase.getRemark())) {
            orderInfo.append("<B>备注：").append(orderBase.getRemark()).append("</B><BR>");
        }
        // 下单时间
        orderInfo.append("<BOLD>下单时间：").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderBase.getCreateTime())).append("</BOLD><BR>");
        // 订单编号
        orderInfo.append("<BOLD>订单号：").append(orderBase.getOrderNo()).append("</BOLD><BR>");
        orderInfo.append("<L>").append("<C>-----商品-----</C><BR>");

        for (int i = 0; i < orderLineList.size(); i++) {
            String title = orderLineList.get(i).getGoodsName() + "/" + orderLineList.get(i).getNameStr();
            String num = orderLineList.get(i).getQuantity().toString();
            String total = orderLineList.get(i).getTotalPrice();
            String price = "" + Double.parseDouble(total) / Integer.parseInt(num);
            price = addSpace(price, b2);
            if (Integer.parseInt(num) > 1) {
                num = "【x" + num + "】";
            } else {
                num = "x" + num;
            }
            num = addSpace(num, b3);
            total = addSpace(total, b4);
            String otherStr = " " + num + " " + price + total;

            int tl = 0;
            try {
                tl = title.getBytes("GBK").length;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            int spaceNum = (tl / b1 + 1) * b1 - tl;
            if (tl < b1) {
                for (int k = 0; k < spaceNum; k++) {
                    title += " ";
                }
                title += otherStr;
            } else if (tl == b1) {
                title += otherStr;
            } else {
                List<String> list = null;
                if (isEn(title)) {
                    list = getStrList(title, b1);
                } else {
                    list = getStrList(title, b1 / 2);
                }
                String s0 = titleAddSpace(list.get(0));
                // 添加 单价 数量 总额
                title = s0 + otherStr + "<BR>";
                String s = "";
                for (int k = 1; k < list.size(); k++) {
                    s += list.get(k);
                }
                try {
                    s = getStringByEnter(b1, s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                title += s;
            }
//            orderInfo += title + "<BR>";
            orderInfo.append(title).append("</L>").append("<BR>");
        }
        if (isRefundOrder) {
            orderInfo.append("<C>********** #").append(" 完**********</C>");
        } else {
            orderInfo.append("<C>-----优惠-----</C><BR>");
            orderInfo.append("打包费：<RIGHT>").append(orderPay.getPackAmount()).append("</RIGHT><BR>");
            orderInfo.append("配送费：<RIGHT>").append(orderPay.getDeliveryAmount()).append("</RIGHT><BR>");
            orderInfo.append("<C>**************************</C><BR>");
            orderInfo.append("订单金额：<RIGHT>").append(orderPay.getAmount()).append("</RIGHT><BR>");
            orderInfo.append("优惠金额：<RIGHT>").append(orderPay.getDiscountAmount()).append("</RIGHT><BR>");
            orderInfo.append("<B>实付：<RIGHT>").append(orderPay.getPayAmount()).append("</RIGHT></B><BR>");

            if (orderBase.getType() == 2) {
                orderInfo.append("<C>------自提用户信息------</C><BR>").append("<L>");
            } else {
                orderInfo.append("<C>------收货地址------</C><BR>").append("<L>");
                orderInfo.append(orderDelivery.getAddress()).append("<BR>");
            }
            orderInfo.append(orderDelivery.getName());
            if (orderDelivery.getSex() != null)
                orderInfo.append(orderDelivery.getSex() == 0 ? "（先生）" : "（女士）<BR><BR>");
            orderInfo.append("电话：").append(orderDelivery.getMobile()).append("<BR>");
            orderInfo.append("<C>********** #").append(index).append(" 完**********</C></L>");
        }
        return orderInfo.toString();
    }

    private static String titleAddSpace(String str) {
        int k = 0;
        int b = 14;
        try {
            k = str.getBytes("GBK").length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < b - k; i++) {
            str += " ";
        }
        return str;
    }

    private static String getStringByEnter(int length, String string) throws Exception {
        for (int i = 1; i <= string.length(); i++) {
            if (string.substring(0, i).getBytes("GBK").length > length) {
                return string.substring(0, i - 1) + "<BR>" + getStringByEnter(length, string.substring(i - 1));
            }
        }
        return string;
    }

    private static String addSpace(String str, int size) {
        int len = str.length();
        if (len < size) {
            for (int i = 0; i < size - len; i++) {
                str += " ";
            }
        }
        return str;
    }

    private static Boolean isEn(String str) {
        boolean b = false;
        try {
            b = str.getBytes("GBK").length == str.length();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return b;
    }

    private static List<String> getStrList(String inputString, int length) {
        int size = inputString.length() / length;
        if (inputString.length() % length != 0) {
            size += 1;
        }
        return getStrList(inputString, length, size);
    }

    private static List<String> getStrList(String inputString, int length, int size) {
        List<String> list = new ArrayList<String>();
        for (int index = 0; index < size; index++) {
            String childStr = substring(inputString, index * length, (index + 1) * length);
            list.add(childStr);
        }
        return list;
    }

    private static String substring(String str, int f, int t) {
        if (f > str.length())
            return null;
        if (t > str.length()) {
            return str.substring(f);
        } else {
            return str.substring(f, t);
        }
    }

}
